package me.zhengjie.service.impl;

import lombok.RequiredArgsConstructor;
import me.zhengjie.WcsReport.BuzzerService;
import me.zhengjie.WcsReport.WcsReportService;
import me.zhengjie.agvSend.AgvSendService;
import me.zhengjie.pojo.dto.*;
import me.zhengjie.pojo.entity.*;
import me.zhengjie.pojo.vo.ReturnVo;
import me.zhengjie.service.PdaService;
import me.zhengjie.sqlservice.*;
import me.zhengjie.utility.IdWorker;
import me.zhengjie.utility.liftState.PriorityEnum;
import me.zhengjie.utility.state.MaterialStatus;
import me.zhengjie.utility.state.TaskStatus;
import me.zhengjie.utility.state.TaskType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class PdaServiceImpl implements PdaService {
    private static final Logger pda = LoggerFactory.getLogger("pda");

    private final IwsStoreOutsideService iwsStoreOutsideService;

    private final AgvSendService agvSendService;

    private final IdWorker idWorker;

    private final WcsDeliveryMissionService wcsDeliveryMissionService;

    private final WcsReportService wcsReportService;

    private final WcsInboundMissionService wcsInboundMissionService;

    private final NestingMiddleTableService nestingMiddleTableService;


    private final WcsLineBodyInboundService wcsLineBodyService;

    private final WcsLineBodyAbnormalService wcsLineBodyAbnormalService;

    private final BuzzerService buzzerService;

    private final WcsLineEdgeWarehouseService wcsLineEdgeWarehouseService;

    private final WcsAgvReleaseGoodsService wcsAgvReleaseGoodsService;



    //点对点叫车
    @Override
    @Transactional
    public ReturnVo pdaPointToPointCallCar(PdaPointToPointCallCarDto pdaPointToPointCallCarDto) {
        String floor = pdaPointToPointCallCarDto.getFloor();
        String storageCode = pdaPointToPointCallCarDto.getStorageCode();
        //起点储位不能小于3
        WcsLineEdgeWarehouse wcsLineEdgeWarehouses = wcsLineEdgeWarehouseService.selectLtStatus(storageCode,TaskStatus.LINE_EDGE_WAREHOUSE_OCCUPIED.getStatus());
        pda.info("点对点叫车，查询数据：{}",wcsLineEdgeWarehouses);
        if (wcsLineEdgeWarehouses == null){
            //起点储位无栈板
            return ReturnVo.ng("起点储位无栈板");
        }
        //起点储位修改为1预定
        boolean b3 = wcsLineEdgeWarehouseService.updateStatusIsAgv(storageCode, null, TaskStatus.LINE_EDGE_WAREHOUSE_RESERVED.getStatus(), 1);
        if (!b3){
            pda.error("点对点叫车入库修改起点储位异常");
            throw new RuntimeException("点对点叫车入库修改起点储位异常");
        }
        if (TaskType.THREE_FLOOR.getMessage().equals(floor)) {
            //3楼入库配送到线体
            WcsLineBodyInbound wcsLineBody = wcsLineBodyService.selectOne();
            String chainMachineStorage = wcsLineBody.getChainMachineStorage();
            //发送AGV任务
            //储位绑定栈板
            String inboundCode = String.valueOf(idWorker.nextId());
            //创建入库任务
            WcsInboundMission wcsInboundMission = new WcsInboundMission();
            wcsInboundMission.setInboundCode(inboundCode);
            wcsInboundMission.setMissionStatus(TaskStatus.task_send.getStatus());
            wcsInboundMission.setContainerCode("半成品入库三楼PLC");
            wcsInboundMission.setSource(storageCode);
            wcsInboundMission.setDestination(chainMachineStorage);
            wcsInboundMission.setContainerType(TaskType.THREE_WORKBIN.getStatus());
            wcsInboundMission.setCreateTime(LocalDateTime.now());
            wcsInboundMission.setUpdateTime(LocalDateTime.now());
            wcsInboundMission.setInboundType(TaskType.inbound_ordinary.getStatus());
            wcsInboundMission.setFloor(TaskType.THREE_FLOOR.getMessage());
            wcsInboundMission.setPriority(5);
            wcsInboundMission.setIsNest(0);
            wcsInboundMission.setIsPlc(1);
            wcsInboundMission.setIsWms(0);
            boolean b1 = wcsInboundMissionService.insertInboundS(wcsInboundMission);
            if (!b1) {
                pda.error("点对点叫车，创建配送任务失败，数据库异常");
                throw new RuntimeException("点对点叫车，创建配送任务失败，数据库异常");
            }
//            CarrierUnbindDto carrierUnbindDto = new CarrierUnbindDto();
//            carrierUnbindDto.setSlotCategory(TaskType.SITE.getMessage());
//            carrierUnbindDto.setSlotCode(storageCode);
//            carrierUnbindDto.setCarrierCategory("PALLET");
//            carrierUnbindDto.setCarrierType("1");
//            carrierUnbindDto.setInvoke(TaskType.BIND.getMessage());
//            agvSendService.carrierUnbind(carrierUnbindDto);
            //2，楼下料点有储位，下发AGV任务
            AgvTaskSubmitDto agvTaskSubmitDto = new AgvTaskSubmitDto();
//                //todo 任务类型，根据现场情况来定
            agvTaskSubmitDto.setTaskType("PC-AMR-TY");
            ArrayList<TargetRoute> targetRouteList = new ArrayList<>();
            TargetRoute targetRoute = new TargetRoute();
            TargetRoute targetRoutes = new TargetRoute();
            //添加起点
            targetRoute.setSeq(0);
            targetRoute.setType(TaskType.SITE.getMessage());
            targetRoute.setCode(storageCode);
            //添加终点
            targetRoutes.setSeq(1);
            targetRoutes.setType(TaskType.SITE.getMessage());
            targetRoutes.setCode(chainMachineStorage);
            targetRouteList.add(targetRoute);
            targetRouteList.add(targetRoutes);
            agvTaskSubmitDto.setTargetRoute(targetRouteList);
            agvTaskSubmitDto.setRobotTaskCode(inboundCode);
            agvTaskSubmitDto.setInitPriority(PriorityEnum.FOUR.getWeight());
            String taskCode = agvSendService.agvTaskSubmit(agvTaskSubmitDto);
            if (taskCode != null) {
                //创建agv放货数据，等待agv申请放货请求
                WcsAgvReleaseGoods wcsAgvReleaseGoods = new WcsAgvReleaseGoods();
                wcsAgvReleaseGoods.setTaskCode(inboundCode);
                wcsAgvReleaseGoods.setCreateTime(LocalDateTime.now());
                wcsAgvReleaseGoods.setApplyReleaseGoodsStatus(TaskStatus.APPLY_RELEASE_GOODS_DEFAULT.getStatus());
                wcsAgvReleaseGoods.setPattern(TaskStatus.INBOUND_PATTERN_ANTI_CARGO.getStatus());
                wcsAgvReleaseGoods.setFloor(TaskType.THREE_FLOOR.getStatus());
                boolean b = wcsAgvReleaseGoodsService.insert(wcsAgvReleaseGoods);
                if (!b) {
                    pda.error("创建agv放货表失败");
                    throw new RuntimeException("创建agv放货表失败");
                }
                return ReturnVo.OK();
            }
            throw  new RuntimeException("下发任务给AGVC失败");
//            return ReturnVo.ng("下发任务给AGVC失败");
        }
        List<WcsLineEdgeWarehouse> iwsSOutsides = wcsLineEdgeWarehouseService.selectFloorIdleStatusContainerCodeIsNull(floor, 0);
        //根据楼层查询库外下料点是否有储位
        if (!iwsSOutsides.isEmpty()) {
            WcsLineEdgeWarehouse wcsLineEdgeWarehouse = iwsSOutsides.get(0);
            String destinationCode = wcsLineEdgeWarehouse.getStorageCode();
            String containerCode = wcsLineEdgeWarehouse.getContainerCode();
            String deliveryCode = String.valueOf(idWorker.nextId());
            //储位绑定栈板
            CarrierUnbindDto carrierUnbindDto = new CarrierUnbindDto();
            carrierUnbindDto.setSlotCategory(TaskType.SITE.getMessage());
            carrierUnbindDto.setSlotCode(storageCode);
            carrierUnbindDto.setCarrierCategory("PALLET");
            carrierUnbindDto.setCarrierType("1");
            carrierUnbindDto.setInvoke(TaskType.BIND.getMessage());
            agvSendService.carrierUnbind(carrierUnbindDto);
            //2，楼下料点有储位，下发AGV任务
            AgvTaskSubmitDto agvTaskSubmitDto = new AgvTaskSubmitDto();
            //todo 任务类型，根据现场情况来定
            agvTaskSubmitDto.setTaskType(TaskType.PF_FMR_COMMON.getMessage());
            ArrayList<TargetRoute> targetRouteList = new ArrayList<>();
            TargetRoute targetRoute = new TargetRoute();
            TargetRoute targetRoutes = new TargetRoute();
            //添加起点
            targetRoute.setSeq(0);
            targetRoute.setType(TaskType.SITE.getMessage());
            targetRoute.setCode(storageCode);
            //添加终点
            targetRoutes.setSeq(1);
            targetRoutes.setType(TaskType.SITE.getMessage());
            targetRoutes.setCode(destinationCode);
            targetRouteList.add(targetRoute);
            targetRouteList.add(targetRoutes);
            agvTaskSubmitDto.setTargetRoute(targetRouteList);
            agvTaskSubmitDto.setRobotTaskCode(deliveryCode);
            agvTaskSubmitDto.setInitPriority(PriorityEnum.FOUR.getWeight());
            String taskCode = agvSendService.agvTaskSubmit(agvTaskSubmitDto);
            if (taskCode != null) {
                //创建配送任务
                WcsDeliveryMission wcsDeliveryMission = new WcsDeliveryMission();
                wcsDeliveryMission.setDeliveryCode(deliveryCode);
                wcsDeliveryMission.setMissionStatus(TaskStatus.task_send.getStatus());
                wcsDeliveryMission.setContainerCode(containerCode);
                wcsDeliveryMission.setSource(storageCode);
                wcsDeliveryMission.setDestination(destinationCode);
                wcsDeliveryMission.setCreateTime(LocalDateTime.now());
                wcsDeliveryMission.setUpdateTime(LocalDateTime.now());
                wcsDeliveryMission.setContainerType(TaskType.PALLET.getStatus());
                wcsDeliveryMission.setReportWms(0);
                wcsDeliveryMission.setFloor(floor);
                boolean b1 = wcsDeliveryMissionService.insertDelivery(wcsDeliveryMission);
                if (!b1) {
                    pda.error("点对点叫车，创建配送任务失败，数据库异常");
                    throw new RuntimeException("点对点叫车，创建配送任务失败，数据库异常");
                }
                //将终点储位绑定
                //CCD储位修改状态
                boolean b2 = wcsLineEdgeWarehouseService.updateStatusIsAgv(destinationCode, null, TaskStatus.LINE_EDGE_WAREHOUSE_RESERVED.getStatus(), 1);

                return ReturnVo.OK();
            }
        }
        return ReturnVo.ng("无空闲储位");
    }

//    @Override
//    public ReturnVo circleLibrary(String storageCode) {
//        //将储位信息发送给WMS获取栈板信息
//        ReturnVo returnVo = wcsReportService.circleLibraryObtainPalletCode(storageCode);
//        pda.info("1楼回库请求参数：{},获取栈板信息：{}", storageCode, returnVo);
//        if (returnVo.getCode() != 200) {
//            return returnVo;
//        }
//        String palletCode = (String) returnVo.getData();
//        InboundStorageApplyDto1 inboundStorageApplyDto = new InboundStorageApplyDto1();
//        inboundStorageApplyDto.setContainerCode(palletCode);
//        inboundStorageApplyDto.setFloor(String.valueOf(TaskType.ONE_FLOOR.getMessage()));
//        inboundStorageApplyDto.setNest(true);
////        List<NestingMiddleTable> nestingMiddleTables = nestingMiddleTableService.selectContainerCode(palletCode);
//        inboundStorageApplyDto.setData(null);
//        //发送WMS申请入库请求终点储位
//        String destinationStorageCode = wcsReportService.inboundStorageApply(inboundStorageApplyDto);
//        TestVo testVo = wcsReportService.wmsInventoryInformation(palletCode);
//        Integer code = testVo.getCode();
//        StringBuilder sb = new StringBuilder();
//        if (code == 200){
//            List<MaterialDao> materialDaoList = testVo.getData();
//            if (!materialDaoList.isEmpty()){
//                List<String> materialCodeList = materialDaoList.stream().map(MaterialDao::getMaterialCode).distinct().collect(Collectors.toList());
//                for (String materialCode : materialCodeList) {
//                    if (sb.length() >0){
//                        sb.append(",");
//                    }
//                    sb.append(materialCode);
//                }
//            }else {
//                return ReturnVo.ng("在WMS未找到库存信息");
//            }
//        }else {
//            return ReturnVo.ng("在WMS未找到库存信息");
//        }
//        pda.info("1楼回库请求参数：{},返回结果：{}", inboundStorageApplyDto, destinationStorageCode);
//        if (destinationStorageCode != null) {
//            //储位绑定栈板
//            CarrierUnbindDto carrierUnbindDto = new CarrierUnbindDto();
//            carrierUnbindDto.setSlotCategory(TaskType.SITE.getMessage());
//            carrierUnbindDto.setSlotCode(storageCode);
//            carrierUnbindDto.setCarrierCategory("PALLET");
//            carrierUnbindDto.setCarrierType("1");
//            carrierUnbindDto.setInvoke(TaskType.BIND.getMessage());
//            agvSendService.carrierUnbind(carrierUnbindDto);
//
//            //发送AGV起点-中间点-终点
//            AgvTaskSubmitDto agvTaskSubmitDto = new AgvTaskSubmitDto();
//            //todo 任务类型，根据现场情况来定
//            agvTaskSubmitDto.setTaskType(TaskType.PF_FMR_TASK_CONTINUE.getMessage());
//            ArrayList<TargetRoute> targetRouteList = new ArrayList<>();
//            TargetRoute targetRoute = new TargetRoute();
//            TargetRoute targetRoutes = new TargetRoute();
//            //添加起点
//            targetRoute.setSeq(0);
//            targetRoute.setType(TaskType.SITE.getMessage());
//            targetRoute.setCode(storageCode);
//            //添加终点
//            targetRoutes.setSeq(1);
//            targetRoutes.setType(TaskType.SITE.getMessage());
//            targetRoutes.setCode(TaskType.ONE_FLOOR_RETURN_TO_STORAGE_LOCATION.getMessage());
//            targetRouteList.add(targetRoute);
//            targetRouteList.add(targetRoutes);
//            agvTaskSubmitDto.setTargetRoute(targetRouteList);
//            String inboundCode = String.valueOf(idWorker.nextId());
//            agvTaskSubmitDto.setRobotTaskCode(inboundCode);
//            agvTaskSubmitDto.setInitPriority(99);
//            String taskCode = agvSendService.agvTaskSubmit(agvTaskSubmitDto);
//            if (taskCode != null) {
//                //创建回库任务
//                WcsInboundMission wcsInboundMission = new WcsInboundMission();
//                wcsInboundMission.setInboundCode(inboundCode);
//                wcsInboundMission.setMissionStatus(TaskStatus.task_send.getStatus());
//                wcsInboundMission.setContainerCode(palletCode);
//                wcsInboundMission.setSource(storageCode);
//                wcsInboundMission.setDestination(destinationStorageCode);
//                wcsInboundMission.setContainerType(4);
//                wcsInboundMission.setCreateTime(LocalDateTime.now());
//                wcsInboundMission.setUpdateTime(LocalDateTime.now());
//                wcsInboundMission.setInboundType(TaskType.circle_library_sorting.getStatus());
//                wcsInboundMission.setIsNest(1);
//                wcsInboundMission.setIsPlc(0);
//                String materialCode = sb.toString();
//                wcsInboundMission.setMaterialCode(materialCode);
//                boolean b = wcsInboundMissionService.insertInbound(wcsInboundMission);
//                if (!b) {
//                    pda.error("创建入库任务失败");
//                    throw new RuntimeException("创建入库任务失败");
//                }
//            }else {
//                CancelInboundStorageDto cancelInboundStorageDto = new CancelInboundStorageDto();
//                cancelInboundStorageDto.setStorageId(destinationStorageCode);
//                cancelInboundStorageDto.setContainerCode(palletCode);
//                cancelInboundStorageDto.setNest(true);
//                //任务下发失败，通知WMS取消入库申请储位
//                boolean b = wcsReportService.cancelInboundStorage(cancelInboundStorageDto);
//                return ReturnVo.ng("任务下发,AGV接收任务失败");
//            }
//            return ReturnVo.OK();
//        }
//        return ReturnVo.ng("未找到合适的终点储位");
//    }

    //扫储位码释放储位
    @Override
    @Transactional
    public ReturnVo pdaStorageRelease(String storage) {
        IwsStoreOutside iwsSOutside = iwsStoreOutsideService.selectStorageCode(storage);
        if (iwsSOutside == null) {
            return ReturnVo.ng("当前储位不是库外储位,释放失败");
        }
        boolean b = iwsStoreOutsideService.updateStatus(storage, null, 0);
        if (!b) {
            return ReturnVo.ng("数据库异常,释放失败");
        }
        //上报agv储位释放
        //储位绑定栈板
        String inboundCode = String.valueOf(idWorker.nextId());
        CarrierUnbindDto carrierUnbindDto = new CarrierUnbindDto();
        carrierUnbindDto.setSlotCategory(TaskType.SITE.getMessage());
        carrierUnbindDto.setSlotCode(storage);
        carrierUnbindDto.setCarrierCategory("PALLET");
        carrierUnbindDto.setCarrierType("1");
        carrierUnbindDto.setInvoke(TaskType.UNBIND.getMessage());
        agvSendService.carrierUnbind(carrierUnbindDto);

//        String storeName = iwsSOutside.getStoreName();
//        if (Objects.equals(storeName, TaskType.STORAGE_TYPE_ONE_FLOOR_NEW_ABNORMAL.getMessage())){
//            //上报单片机数量
//            List<IwsSOutside> iwsSOutsideList= iwsSOutsideService.selectStoreName(TaskType.STORAGE_TYPE_ONE_FLOOR_NEW_ABNORMAL.getMessage());
//                McuDto mcuDto = new McuDto();
//                ArrayList<McuCount> mcuCounts = new ArrayList<>();
//                McuCount mcuCount = new McuCount();
//                mcuCount.setCount(iwsSOutsideList.size());
//                mcuCounts.add(mcuCount);
//                mcuDto.setDetails(mcuCounts);
//                buzzerService.mcuSend(mcuDto,"127.0.0.1:0000");
//        }else if (Objects.equals(storeName, TaskType.STORAGE_TYPE_THREE_FLOOR_NEW_ABNORMAL.getMessage())){
//            //上报单片机数量
//            List<IwsSOutside> iwsSOutsideList= iwsSOutsideService.selectStoreName(TaskType.STORAGE_TYPE_THREE_FLOOR_NEW_ABNORMAL.getMessage());
//                McuDto mcuDto = new McuDto();
//                ArrayList<McuCount> mcuCounts = new ArrayList<>();
//                McuCount mcuCount = new McuCount();
//                mcuCount.setCount(iwsSOutsideList.size());
//                mcuCounts.add(mcuCount);
//                mcuDto.setDetails(mcuCounts);
//                buzzerService.mcuSend(mcuDto,"127.0.0.1:0000");
//        }
        return ReturnVo.OK();
    }

    @Override
    public ReturnVo vehicleNesting(String containerCode) {
        //查询嵌套信息
        List<NestingMiddleTable> nestingMiddleTables = nestingMiddleTableService.selectContainerCode(containerCode);
        if (nestingMiddleTables.isEmpty()) {
            return ReturnVo.ng("未查询到嵌套信息");
        } else {
            long rawMaterialsQ = nestingMiddleTables.stream().filter(f -> f.getMaterialCategory().equals(TaskType.MATERIAL_Q.getMessage())).count();
            if (rawMaterialsQ != 0) {
                //判断是否自检
                long rawMaterialsQQualified = nestingMiddleTables.stream().filter(f -> f.getMaterialCategory().equals(TaskType.MATERIAL_Q.getMessage()) && f.getSelfCheckStatus().equals("合格")).count();
                if (rawMaterialsQ == rawMaterialsQQualified) {
                    return ReturnVo.OK();
                }
                return ReturnVo.ng("原物料Q未自检");
            }
        }
        return ReturnVo.ng("未查询到嵌套信息");
    }

    @Transactional
    @Override
    public ReturnVo artificialInbound(ArtificialInboundDto artificialInboundDto) {
        pda.info("人工入库请求参数：{}", artificialInboundDto);
        String containerCode = artificialInboundDto.getContainerCode();
        String storageCode = artificialInboundDto.getStorageCode();
        //向wms发送储位是否可用
        StorageIsAvailableDto storageIsAvailableDto = new StorageIsAvailableDto();
        storageIsAvailableDto.setStoreId(storageCode);
        boolean b1 = wcsReportService.storageIsAvailable(storageIsAvailableDto);
        if (b1) {
            IwsStoreOutside iwsStoreOutside = iwsStoreOutsideService.selectId(storageCode);
            if (iwsStoreOutside != null) {
                String floor = iwsStoreOutside.getFloor();
                //向wms发送储位申请入库
                InboundStorageApplyDto1 inboundStorageApplyDto = new InboundStorageApplyDto1();
                inboundStorageApplyDto.setContainerCode(containerCode);
                inboundStorageApplyDto.setFloor(floor);
                inboundStorageApplyDto.setNest(false);
                List<NestingMiddleTable> nestingMiddleTables = nestingMiddleTableService.selectContainerCode(containerCode);
                if (!nestingMiddleTables.isEmpty()) {
//            NestingMiddleTable nestingMiddleTable = nestingMiddleTables.get(0);
//            String issuePosition = nestingMiddleTable.getIssuePosition();
//            if (!issuePosition.equals(storageCode)) {
//                return ReturnVo.ng("中间表仓位与当前储位不一致");
//            }
                    ArrayList<NestingMiddleTable> materialDaos = new ArrayList<>();
                    for (NestingMiddleTable nestingMiddleTable : nestingMiddleTables) {
                        NestingMiddleTable nestingMiddleTable1 = new NestingMiddleTable();
                        BeanUtils.copyProperties(nestingMiddleTable,nestingMiddleTable1);
                        materialDaos.add(nestingMiddleTable1);
                    }
                    inboundStorageApplyDto.setData(materialDaos);
                    String destination = wcsReportService.inboundStorageApply(inboundStorageApplyDto);
                    if (destination != null) {
                        StringBuilder sb = new StringBuilder();
                        List<String> materialCodeList = nestingMiddleTables.stream().map(NestingMiddleTable::getMaterialCode).distinct().collect(Collectors.toList());
                        for (String materialCode : materialCodeList) {
                            if (sb.length() > 0) {
                                sb.append(",");
                            }
                            sb.append(materialCode);
                        }
                        List<WcsInboundMission> wcsInboundMissionList = wcsInboundMissionService.selectContainerCodeNotTask(containerCode);
                        if (!wcsInboundMissionList.isEmpty()){
                            return new ReturnVo(205,"载具已再AGV任务中",null);
                        }
                        String inboundCode = String.valueOf(idWorker.nextId());
                        //创建入库任务
                        WcsInboundMission wcsInboundMission = new WcsInboundMission();
                        wcsInboundMission.setInboundCode(inboundCode);
                        wcsInboundMission.setMissionStatus(TaskStatus.task_send.getStatus());
                        wcsInboundMission.setContainerCode(containerCode);
                        wcsInboundMission.setSource(storageCode);
                        wcsInboundMission.setDestination(destination);
                        if (TaskType.ONE_FLOOR.getMessage().equals(floor)) {
                            wcsInboundMission.setContainerType(TaskType.PALLET.getStatus());
                        } else if ((TaskType.TWO_FLOOR.getMessage().equals(floor))) {
                            wcsInboundMission.setContainerType(TaskType.WORKBIN.getStatus());
                        } else if ((TaskType.THREE_FLOOR.getMessage().equals(floor))) {
                            wcsInboundMission.setContainerType(TaskType.THREE_WORKBIN.getStatus());
                        }
                        wcsInboundMission.setCreateTime(LocalDateTime.now());
                        wcsInboundMission.setUpdateTime(LocalDateTime.now());
                        wcsInboundMission.setInboundType(TaskType.inbound_ordinary.getStatus());
                        wcsInboundMission.setPriority(90);
                        wcsInboundMission.setIsNest(0);
                        wcsInboundMission.setIsPlc(0);
                        wcsInboundMission.setIsWms(1);
                        String materialCode = sb.toString();
                        wcsInboundMission.setMaterialCode(materialCode);
                        boolean b2 = wcsInboundMissionService.insertInbound(wcsInboundMission);
                        if (!b2) {
                            pda.error("入库任务创建失败");
                            throw new RuntimeException("入库任务创建失败");
                        }
                        //储位绑定栈板
                        CarrierUnbindDto carrierUnbindDto = new CarrierUnbindDto();
                        carrierUnbindDto.setSlotCategory(TaskType.SITE.getMessage());
                        carrierUnbindDto.setSlotCode(storageCode);
                        carrierUnbindDto.setCarrierCategory("PALLET");
                        carrierUnbindDto.setCarrierType("1");
                        carrierUnbindDto.setInvoke(TaskType.BIND.getMessage());
                        agvSendService.carrierUnbind(carrierUnbindDto);
                        //下发agv任务
                        AgvTaskSubmitDto agvTaskSubmitDto = new AgvTaskSubmitDto();
                        //todo 任务类型，根据现场情况来定
                        agvTaskSubmitDto.setTaskType(TaskType.PF_FMR_COMMON.getMessage());
                        ArrayList<TargetRoute> targetRouteList = new ArrayList<>();
                        TargetRoute targetRoute = new TargetRoute();
                        TargetRoute targetRoutes = new TargetRoute();
                        //添加起点
                        targetRoute.setSeq(0);
                        targetRoute.setType(TaskType.STORAGE.getMessage());
                        targetRoute.setCode(storageCode);
                        //添加终点
                        targetRoutes.setSeq(1);
                        targetRoutes.setType(TaskType.STORAGE.getMessage());
                        targetRoutes.setCode(destination);
                        targetRouteList.add(targetRoute);
                        targetRouteList.add(targetRoutes);
                        agvTaskSubmitDto.setTargetRoute(targetRouteList);
                        agvTaskSubmitDto.setRobotTaskCode(inboundCode);
                        agvTaskSubmitDto.setInitPriority(PriorityEnum.FOUR.getWeight());
                        String taskCode = agvSendService.agvTaskSubmit(agvTaskSubmitDto);
                        if (taskCode == null) {
                            //通知WMS取消入庫任務
                            CancelInboundStorageDto cancelInboundStorageDto = new CancelInboundStorageDto();
                            cancelInboundStorageDto.setStorageId(destination);
                            cancelInboundStorageDto.setContainerCode(containerCode);
                            cancelInboundStorageDto.setNest(false);
                            boolean b = wcsReportService.cancelInboundStorage(cancelInboundStorageDto);
                            if (b) {
                                pda.error("下发任务给AGV失败");
                                throw new RuntimeException("下发任务给AGV失败,数据回滚");
                            }
                        } else {

                        }
                        return ReturnVo.OK();
                    }
                    return ReturnVo.ng("入库未找到合适储位");
                }
                return ReturnVo.ng("中间表未嵌套");
            }
            return ReturnVo.ng("未查询到当前储位");
        }
        return ReturnVo.ng("当前储位编码未绑定");
    }

    @Override
    @Transactional
    public ReturnVo threeFloorAbnormal(String container) {
        List<WcsLineBodyAbnormal> wcsLineBodyAbnormal = wcsLineBodyAbnormalService.selectContainer(container);
        if (!wcsLineBodyAbnormal.isEmpty()) {
            WcsLineBodyAbnormal wcsLineBodyAbnormal1 = wcsLineBodyAbnormal.get(0);
            return ReturnVo.OK(wcsLineBodyAbnormal1.getContainerCode() + wcsLineBodyAbnormal1.getAbnormalInformation() + ",时间：" + wcsLineBodyAbnormal1.getCreateTime());
        }
        return ReturnVo.ng(container + "未找到异常问题");
    }

    @Override
    @Transactional
    public ReturnVo floorQueryStorage(String floor) {
        //根据楼层查询
        List<WcsLineEdgeWarehouse> wcsLineEdgeWarehouseList = wcsLineEdgeWarehouseService.floorQueryAvailableStorage(floor);
        if (!wcsLineEdgeWarehouseList.isEmpty()) {
            return ReturnVo.OK(wcsLineEdgeWarehouseList);
        }
        return ReturnVo.ng("当前楼层未查询到空储位");
    }

    @Override
    @Transactional
    public ReturnVo pointToPoint(PointToPointDto pointToPointDto) {
        String source = pointToPointDto.getSource();
        String destination = pointToPointDto.getDestination();
        if (source == null || destination == null) {
            return ReturnVo.ng("起点或终点未传值");
        }
        //起点储位不能小于3
        WcsLineEdgeWarehouse wcsLineEdgeWarehouses = wcsLineEdgeWarehouseService.selectLtStatus(source,TaskStatus.LINE_EDGE_WAREHOUSE_OCCUPIED.getStatus());
        if (wcsLineEdgeWarehouses != null){
            //起点储位无栈板
            return ReturnVo.ng("起点储位无栈板");
        }
        //起点储位修改为1预定
        boolean b3 = wcsLineEdgeWarehouseService.updateStatusIsAgv(source, null, TaskStatus.LINE_EDGE_WAREHOUSE_RESERVED.getStatus(), 1);
        if (!b3){
            pda.error("点对点叫车入库修改起点储位异常");
            throw new RuntimeException("点对点叫车入库修改起点储位异常");
        }
        //创建配送任务
        String deliveryCode = String.valueOf(idWorker.nextId());
        WcsDeliveryMission wcsDeliveryMission = new WcsDeliveryMission();
        wcsDeliveryMission.setDeliveryCode(deliveryCode);
        wcsDeliveryMission.setMissionStatus(TaskStatus.task_send.getStatus());
        wcsDeliveryMission.setSource(source);
        wcsDeliveryMission.setDestination(destination);
        wcsDeliveryMission.setCreateTime(LocalDateTime.now());
        wcsDeliveryMission.setUpdateTime(LocalDateTime.now());
        wcsDeliveryMission.setContainerType(TaskType.PALLET.getStatus());
        wcsDeliveryMission.setReportWms(0);
        boolean b1 = wcsDeliveryMissionService.insertDelivery(wcsDeliveryMission);
        if (!b1) {
            pda.error("点对点叫车，创建配送任务失败，数据库异常");
            throw new RuntimeException("点对点叫车，创建配送任务失败，数据库异常");
        }
        //储位绑定栈板
        String inboundCode = String.valueOf(idWorker.nextId());
        CarrierUnbindDto carrierUnbindDto = new CarrierUnbindDto();
        carrierUnbindDto.setSlotCategory(TaskType.SITE.getMessage());
        carrierUnbindDto.setSlotCode(source);
        carrierUnbindDto.setCarrierCategory("PALLET");
        carrierUnbindDto.setCarrierType("1");
        carrierUnbindDto.setInvoke(TaskType.BIND.getMessage());
        agvSendService.carrierUnbind(carrierUnbindDto);
        AgvTaskSubmitDto agvTaskSubmitDto = new AgvTaskSubmitDto();
        //todo 任务类型，根据现场情况来定
        agvTaskSubmitDto.setTaskType(TaskType.PF_FMR_COMMON.getMessage());
        ArrayList<TargetRoute> targetRouteList = new ArrayList<>();
        TargetRoute targetRoute = new TargetRoute();
        TargetRoute targetRoutes = new TargetRoute();
        //添加起点
        targetRoute.setSeq(0);
        targetRoute.setType(TaskType.SITE.getMessage());
        targetRoute.setCode(source);
        //添加终点
        targetRoutes.setSeq(1);
        targetRoutes.setType(TaskType.SITE.getMessage());
        targetRoutes.setCode(destination);
        targetRouteList.add(targetRoute);
        targetRouteList.add(targetRoutes);
        agvTaskSubmitDto.setTargetRoute(targetRouteList);
        agvTaskSubmitDto.setRobotTaskCode(deliveryCode);
        agvTaskSubmitDto.setInitPriority(PriorityEnum.FOUR.getWeight());
        String taskCode = agvSendService.agvTaskSubmit(agvTaskSubmitDto);
        if (taskCode != null) {
            //将终点储位绑定
//                boolean b = iwsSOutsideService.updateStatus(destinationCode, null, 1);
//                if (!b) {
//                    pda.error("点对点去2楼修改终点储位状态失败");
//                    throw new RuntimeException("点对点去2楼修改终点储位状态失败");
//                }
            //CCD储位修改状态
            boolean b2 = wcsLineEdgeWarehouseService.updateStatusIsAgv(deliveryCode, null, TaskStatus.LINE_EDGE_WAREHOUSE_RESERVED.getStatus(), 1);
        }
        return ReturnVo.OK("点对点叫车成功");
    }

    @Override
    public ReturnVo deliveryCall(DeliveryCallDto deliveryCallDto) {
        String region = deliveryCallDto.getRegion();
        String floor = deliveryCallDto.getFloor();
        String source = deliveryCallDto.getSource();
        String destination = deliveryCallDto.getDestination();
        //根据楼层区域查找终点储位
        List<WcsLineEdgeWarehouse> wcsLineBodyInboundList = wcsLineEdgeWarehouseService.deliveryQuereStorageCode(floor, region, destination);
        if (!wcsLineBodyInboundList.isEmpty()) {
            //起点储位不能小于3
            WcsLineEdgeWarehouse wcsLineEdgeWarehouses = wcsLineEdgeWarehouseService.selectLtStatus(source,TaskStatus.LINE_EDGE_WAREHOUSE_OCCUPIED.getStatus());
            if (wcsLineEdgeWarehouses != null){
                //起点储位无栈板
                return ReturnVo.ng("起点储位无栈板");
            }
            //起点储位修改为1预定
            boolean b3 = wcsLineEdgeWarehouseService.updateStatusIsAgv(source, null, TaskStatus.LINE_EDGE_WAREHOUSE_RESERVED.getStatus(), 1);
            if (!b3){
                pda.error("点对点叫车入库修改起点储位异常");
                throw new RuntimeException("点对点叫车入库修改起点储位异常");
            }

            WcsLineEdgeWarehouse wcsLineEdgeWarehouse = wcsLineBodyInboundList.get(0);
            String deliveryCode = String.valueOf(idWorker.nextId());
            //创建配送任务
            WcsDeliveryMission wcsDeliveryMission = new WcsDeliveryMission();
            wcsDeliveryMission.setDeliveryCode(deliveryCode);
            wcsDeliveryMission.setMissionStatus(TaskStatus.task_send.getStatus());
            wcsDeliveryMission.setSource(source);
            wcsDeliveryMission.setDestination(wcsLineEdgeWarehouse.getStorageCode());
            wcsDeliveryMission.setCreateTime(LocalDateTime.now());
            wcsDeliveryMission.setUpdateTime(LocalDateTime.now());
            wcsDeliveryMission.setReportWms(0);
            boolean b1 = wcsDeliveryMissionService.insertDelivery(wcsDeliveryMission);
            if (!b1) {
                pda.error("点对点叫车，创建配送任务失败，数据库异常");
                throw new RuntimeException("点对点叫车，创建配送任务失败，数据库异常");
            }
            //储位绑定栈板
            CarrierUnbindDto carrierUnbindDto = new CarrierUnbindDto();
            carrierUnbindDto.setSlotCategory(TaskType.SITE.getMessage());
            carrierUnbindDto.setSlotCode(source);
            carrierUnbindDto.setCarrierCategory("PALLET");
            carrierUnbindDto.setCarrierType("1");
            carrierUnbindDto.setInvoke(TaskType.BIND.getMessage());
            agvSendService.carrierUnbind(carrierUnbindDto);
            //2下发AGV任务
            AgvTaskSubmitDto agvTaskSubmitDto = new AgvTaskSubmitDto();
            //todo 任务类型，根据现场情况来定
            agvTaskSubmitDto.setTaskType(TaskType.PF_FMR_COMMON.getMessage());
            ArrayList<TargetRoute> targetRouteList = new ArrayList<>();
            TargetRoute targetRoute = new TargetRoute();
            TargetRoute targetRoutes = new TargetRoute();
            //添加起点
            targetRoute.setSeq(0);
            targetRoute.setType(TaskType.SITE.getMessage());
            targetRoute.setCode(source);
            //添加终点
            targetRoutes.setSeq(1);
            targetRoutes.setType(TaskType.SITE.getMessage());
            targetRoutes.setCode(wcsLineEdgeWarehouse.getStorageCode());
            targetRouteList.add(targetRoute);
            targetRouteList.add(targetRoutes);
            agvTaskSubmitDto.setTargetRoute(targetRouteList);
            agvTaskSubmitDto.setRobotTaskCode(deliveryCode);
            agvTaskSubmitDto.setInitPriority(PriorityEnum.FOUR.getWeight());
            String taskCode = agvSendService.agvTaskSubmit(agvTaskSubmitDto);
            if (taskCode != null) {
                //将终点储位绑定
                //CCD储位修改状态
                boolean b2 = wcsLineEdgeWarehouseService.updateStatusIsAgv(wcsLineEdgeWarehouse.getStorageCode(), null, TaskStatus.LINE_EDGE_WAREHOUSE_RESERVED.getStatus(), 1);
                pda.info("发送agv返回结果：{},修改储位:{}", taskCode, deliveryCode);
                return ReturnVo.OK();
            }
            return null;
        }
        return ReturnVo.ng("未查询到空储位");
    }

    @Override
    public ReturnVo floorQueryRegion(String floor) {
        List<WcsLineEdgeWarehouse> wcsLineEdgeWarehouseList = wcsLineEdgeWarehouseService.queryRegion(floor);
        List<String> collect = wcsLineEdgeWarehouseList.stream().map(WcsLineEdgeWarehouse::getRegion).distinct().collect(Collectors.toList());
        return ReturnVo.OK(collect);
    }

    @Override
    public ReturnVo regionQueryStorage(String region) {
        //根据区域查询可用储位
        List<WcsLineEdgeWarehouse> wcsLineEdgeWarehouseList = wcsLineEdgeWarehouseService.regionQueryAvailableStorage(region);
        if (!wcsLineEdgeWarehouseList.isEmpty()) {
            return ReturnVo.OK(wcsLineEdgeWarehouseList);
        }
        return ReturnVo.ng("当前楼层未查询到空储位");
    }

//    @Override
//    public ReturnVo ccdV2(CameraIpDto cameraIpDto) throws InterruptedException {
//        pda.info("CCD告知有人IP:{}", cameraIpDto);
//        if ("192.168.48.74".equals(cameraIpDto.getCameraIP())){
//            //入库有人通知机械臂停止
//            inboundLineBody.writeWithRetry(501,1,1,3);
//            Thread.sleep(1000);
//            inboundLineBody.writeWithRetry(501,0,1,3);
//            return ReturnVo.OK();
//        }else if ("192.168.48.75".equals(cameraIpDto.getCameraIP())){
//            outboundLineBody.writeWithRetry(501,1,1,3);
//            Thread.sleep(1000);
//            outboundLineBody.writeWithRetry(501,0,1,3);
//            return ReturnVo.OK();
//        }
//        return ReturnVo.ng("PLC异常");
//    }
}
